home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyo (Python 2.3)
-
- __all__ = [
- 'get_close_matches',
- 'ndiff',
- 'restore',
- 'SequenceMatcher',
- 'Differ',
- 'IS_CHARACTER_JUNK',
- 'IS_LINE_JUNK',
- 'context_diff',
- 'unified_diff']
-
- def _calculate_ratio(matches, length):
- if length:
- return 2.0 * matches / length
-
- return 1.0
-
-
- class SequenceMatcher:
-
- def __init__(self, isjunk = None, a = '', b = ''):
- self.isjunk = isjunk
- self.a = self.b = None
- self.set_seqs(a, b)
-
-
- def set_seqs(self, a, b):
- self.set_seq1(a)
- self.set_seq2(b)
-
-
- def set_seq1(self, a):
- if a is self.a:
- return None
-
- self.a = a
- self.matching_blocks = self.opcodes = None
-
-
- def set_seq2(self, b):
- if b is self.b:
- return None
-
- self.b = b
- self.matching_blocks = self.opcodes = None
- self.fullbcount = None
- self._SequenceMatcher__chain_b()
-
-
- def __chain_b(self):
- b = self.b
- n = len(b)
- self.b2j = b2j = { }
- populardict = { }
- for i, elt in enumerate(b):
- if elt in b2j:
- indices = b2j[elt]
- if n >= 200 and len(indices) * 100 > n:
- populardict[elt] = 1
- del indices[:]
- else:
- indices.append(i)
- len(indices) * 100 > n
- b2j[elt] = [
- i]
-
- for elt in populardict:
- del b2j[elt]
-
- isjunk = self.isjunk
- junkdict = { }
- if isjunk:
- for d in (populardict, b2j):
- for elt in d.keys():
- if isjunk(elt):
- junkdict[elt] = 1
- del d[elt]
- continue
-
-
-
- self.isbjunk = junkdict.has_key
- self.isbpopular = populardict.has_key
-
-
- def find_longest_match(self, alo, ahi, blo, bhi):
- (a, b, b2j, isbjunk) = (self.a, self.b, self.b2j, self.isbjunk)
- (besti, bestj, bestsize) = (alo, blo, 0)
- j2len = { }
- nothing = []
- for i in xrange(alo, ahi):
- j2lenget = j2len.get
- newj2len = { }
- for j in b2j.get(a[i], nothing):
- if j < blo:
- continue
-
- if j >= bhi:
- break
-
- k = newj2len[j] = j2lenget(j - 1, 0) + 1
- if k > bestsize:
- (besti, bestj, bestsize) = ((i - k) + 1, (j - k) + 1, k)
- continue
-
- j2len = newj2len
-
- while besti > alo and bestj > blo and not isbjunk(b[bestj - 1]) and a[besti - 1] == b[bestj - 1]:
- (besti, bestj, bestsize) = (besti - 1, bestj - 1, bestsize + 1)
- while besti + bestsize < ahi and bestj + bestsize < bhi and not isbjunk(b[bestj + bestsize]) and a[besti + bestsize] == b[bestj + bestsize]:
- bestsize += 1
- while besti > alo and bestj > blo and isbjunk(b[bestj - 1]) and a[besti - 1] == b[bestj - 1]:
- (besti, bestj, bestsize) = (besti - 1, bestj - 1, bestsize + 1)
- while besti + bestsize < ahi and bestj + bestsize < bhi and isbjunk(b[bestj + bestsize]) and a[besti + bestsize] == b[bestj + bestsize]:
- bestsize = bestsize + 1
- return (besti, bestj, bestsize)
-
-
- def get_matching_blocks(self):
- if self.matching_blocks is not None:
- return self.matching_blocks
-
- self.matching_blocks = []
- (la, lb) = (len(self.a), len(self.b))
- self._SequenceMatcher__helper(0, la, 0, lb, self.matching_blocks)
- self.matching_blocks.append((la, lb, 0))
- return self.matching_blocks
-
-
- def __helper(self, alo, ahi, blo, bhi, answer):
- (i, j, k) = x = self.find_longest_match(alo, ahi, blo, bhi)
- if k:
- if alo < i and blo < j:
- self._SequenceMatcher__helper(alo, i, blo, j, answer)
-
- answer.append(x)
- if i + k < ahi and j + k < bhi:
- self._SequenceMatcher__helper(i + k, ahi, j + k, bhi, answer)
-
-
-
-
- def get_opcodes(self):
- if self.opcodes is not None:
- return self.opcodes
-
- i = j = 0
- self.opcodes = answer = []
- for ai, bj, size in self.get_matching_blocks():
- tag = ''
- if i < ai and j < bj:
- tag = 'replace'
- elif i < ai:
- tag = 'delete'
- elif j < bj:
- tag = 'insert'
-
- if tag:
- answer.append((tag, i, ai, j, bj))
-
- (i, j) = (ai + size, bj + size)
- if size:
- answer.append(('equal', ai, i, bj, j))
- continue
-
- return answer
-
-
- def get_grouped_opcodes(self, n = 3):
- codes = self.get_opcodes()
- if codes[0][0] == 'equal':
- (tag, i1, i2, j1, j2) = codes[0]
- codes[0] = (tag, max(i1, i2 - n), i2, max(j1, j2 - n), j2)
-
- if codes[-1][0] == 'equal':
- (tag, i1, i2, j1, j2) = codes[-1]
- codes[-1] = (tag, i1, min(i2, i1 + n), j1, min(j2, j1 + n))
-
- nn = n + n
- group = []
- for tag, i1, i2, j1, j2 in codes:
- if tag == 'equal' and i2 - i1 > nn:
- group.append((tag, i1, min(i2, i1 + n), j1, min(j2, j1 + n)))
- yield group
- group = []
- (i1, j1) = (max(i1, i2 - n), max(j1, j2 - n))
-
- group.append((tag, i1, i2, j1, j2))
-
- if group:
- if len(group) == 1:
- pass
- if not (group[0][0] == 'equal'):
- yield group
-
-
-
- def ratio(self):
- matches = reduce((lambda sum, triple: sum + triple[-1]), self.get_matching_blocks(), 0)
- return _calculate_ratio(matches, len(self.a) + len(self.b))
-
-
- def quick_ratio(self):
- if self.fullbcount is None:
- self.fullbcount = fullbcount = { }
- for elt in self.b:
- fullbcount[elt] = fullbcount.get(elt, 0) + 1
-
-
- fullbcount = self.fullbcount
- avail = { }
- (availhas, matches) = (avail.has_key, 0)
- for elt in self.a:
- if availhas(elt):
- numb = avail[elt]
- else:
- numb = fullbcount.get(elt, 0)
- avail[elt] = numb - 1
- if numb > 0:
- matches = matches + 1
- continue
-
- return _calculate_ratio(matches, len(self.a) + len(self.b))
-
-
- def real_quick_ratio(self):
- (la, lb) = (len(self.a), len(self.b))
- return _calculate_ratio(min(la, lb), la + lb)
-
-
-
- def get_close_matches(word, possibilities, n = 3, cutoff = 0.59999999999999998):
- if not (n > 0):
- raise ValueError('n must be > 0: ' + `n`)
-
- if not None if cutoff <= cutoff else cutoff <= 1.0:
- raise ValueError('cutoff must be in [0.0, 1.0]: ' + `cutoff`)
-
- result = []
- s = SequenceMatcher()
- s.set_seq2(word)
- for x in possibilities:
- s.set_seq1(x)
- if s.real_quick_ratio() >= cutoff and s.quick_ratio() >= cutoff and s.ratio() >= cutoff:
- result.append((s.ratio(), x))
- continue
-
- result.sort()
- result = result[-n:]
- result.reverse()
- return [ x for score, x in result ]
-
-
- def _count_leading(line, ch):
- (i, n) = (0, len(line))
- while i < n and line[i] == ch:
- i += 1
- return i
-
-
- class Differ:
-
- def __init__(self, linejunk = None, charjunk = None):
- self.linejunk = linejunk
- self.charjunk = charjunk
-
-
- def compare(self, a, b):
- cruncher = SequenceMatcher(self.linejunk, a, b)
- for tag, alo, ahi, blo, bhi in cruncher.get_opcodes():
- if tag == 'replace':
- g = self._fancy_replace(a, alo, ahi, b, blo, bhi)
- elif tag == 'delete':
- g = self._dump('-', a, alo, ahi)
- elif tag == 'insert':
- g = self._dump('+', b, blo, bhi)
- elif tag == 'equal':
- g = self._dump(' ', a, alo, ahi)
- else:
- raise ValueError, 'unknown tag ' + `tag`
- for line in g:
- yield line
-
-
-
-
- def _dump(self, tag, x, lo, hi):
- for i in xrange(lo, hi):
- yield '%s %s' % (tag, x[i])
-
-
-
- def _plain_replace(self, a, alo, ahi, b, blo, bhi):
- if bhi - blo < ahi - alo:
- first = self._dump('+', b, blo, bhi)
- second = self._dump('-', a, alo, ahi)
- else:
- first = self._dump('-', a, alo, ahi)
- second = self._dump('+', b, blo, bhi)
- for g in (first, second):
- for line in g:
- yield line
-
-
-
-
- def _fancy_replace(self, a, alo, ahi, b, blo, bhi):
- (best_ratio, cutoff) = (0.73999999999999999, 0.75)
- cruncher = SequenceMatcher(self.charjunk)
- (eqi, eqj) = (None, None)
- for j in xrange(blo, bhi):
- bj = b[j]
- cruncher.set_seq2(bj)
- for i in xrange(alo, ahi):
- ai = a[i]
- if ai == bj:
- if eqi is None:
- (eqi, eqj) = (i, j)
- continue
- continue
-
- cruncher.set_seq1(ai)
- if cruncher.real_quick_ratio() > best_ratio and cruncher.quick_ratio() > best_ratio and cruncher.ratio() > best_ratio:
- (best_ratio, best_i, best_j) = (cruncher.ratio(), i, j)
- continue
-
-
- if best_ratio < cutoff:
- if eqi is None:
- for line in self._plain_replace(a, alo, ahi, b, blo, bhi):
- yield line
-
- return None
-
- (best_i, best_j, best_ratio) = (eqi, eqj, 1.0)
- else:
- eqi = None
- for line in self._fancy_helper(a, alo, best_i, b, blo, best_j):
- yield line
-
- (aelt, belt) = (a[best_i], b[best_j])
- if eqi is None:
- atags = btags = ''
- cruncher.set_seqs(aelt, belt)
- for tag, ai1, ai2, bj1, bj2 in cruncher.get_opcodes():
- (la, lb) = (ai2 - ai1, bj2 - bj1)
- if tag == 'replace':
- atags += '^' * la
- btags += '^' * lb
- continue
- if tag == 'delete':
- atags += '-' * la
- continue
- if tag == 'insert':
- btags += '+' * lb
- continue
- if tag == 'equal':
- atags += ' ' * la
- btags += ' ' * lb
- continue
- raise ValueError, 'unknown tag ' + `tag`
-
- for line in self._qformat(aelt, belt, atags, btags):
- yield line
-
- else:
- yield ' ' + aelt
- for line in self._fancy_helper(a, best_i + 1, ahi, b, best_j + 1, bhi):
- yield line
-
-
-
- def _fancy_helper(self, a, alo, ahi, b, blo, bhi):
- g = []
- if alo < ahi:
- if blo < bhi:
- g = self._fancy_replace(a, alo, ahi, b, blo, bhi)
- else:
- g = self._dump('-', a, alo, ahi)
- elif blo < bhi:
- g = self._dump('+', b, blo, bhi)
-
- for line in g:
- yield line
-
-
-
- def _qformat(self, aline, bline, atags, btags):
- common = min(_count_leading(aline, '\t'), _count_leading(bline, '\t'))
- common = min(common, _count_leading(atags[:common], ' '))
- atags = atags[common:].rstrip()
- btags = btags[common:].rstrip()
- yield '- ' + aline
- if atags:
- yield '? %s%s\n' % ('\t' * common, atags)
-
- yield '+ ' + bline
- if btags:
- yield '? %s%s\n' % ('\t' * common, btags)
-
-
-
- import re
-
- def IS_LINE_JUNK(line, pat = re.compile('\\s*#?\\s*$').match):
- return pat(line) is not None
-
-
- def IS_CHARACTER_JUNK(ch, ws = ' \t'):
- return ch in ws
-
- del re
-
- def unified_diff(a, b, fromfile = '', tofile = '', fromfiledate = '', tofiledate = '', n = 3, lineterm = '\n'):
- started = False
- for group in SequenceMatcher(None, a, b).get_grouped_opcodes(n):
- if not started:
- yield '--- %s %s%s' % (fromfile, fromfiledate, lineterm)
- yield '+++ %s %s%s' % (tofile, tofiledate, lineterm)
- started = True
-
- (i1, i2, j1, j2) = (group[0][1], group[-1][2], group[0][3], group[-1][4])
- yield '@@ -%d,%d +%d,%d @@%s' % (i1 + 1, i2 - i1, j1 + 1, j2 - j1, lineterm)
- for tag, i1, i2, j1, j2 in group:
- if tag == 'equal':
- for line in a[i1:i2]:
- yield ' ' + line
-
- continue
-
- if tag == 'replace' or tag == 'delete':
- for line in a[i1:i2]:
- yield '-' + line
-
-
- if tag == 'replace' or tag == 'insert':
- for line in b[j1:j2]:
- yield '+' + line
-
-
-
-
-
- def context_diff(a, b, fromfile = '', tofile = '', fromfiledate = '', tofiledate = '', n = 3, lineterm = '\n'):
- started = False
- prefixmap = {
- 'insert': '+ ',
- 'delete': '- ',
- 'replace': '! ',
- 'equal': ' ' }
- for group in SequenceMatcher(None, a, b).get_grouped_opcodes(n):
- if not started:
- yield '*** %s %s%s' % (fromfile, fromfiledate, lineterm)
- yield '--- %s %s%s' % (tofile, tofiledate, lineterm)
- started = True
-
- yield '***************%s' % (lineterm,)
- if group[-1][2] - group[0][1] >= 2:
- yield '*** %d,%d ****%s' % (group[0][1] + 1, group[-1][2], lineterm)
- else:
- yield '*** %d ****%s' % (group[-1][2], lineterm)
- visiblechanges = []
- if visiblechanges:
- for tag, i1, i2, _, _ in group:
- if tag != 'insert':
- for line in a[i1:i2]:
- yield prefixmap[tag] + line
-
-
-
- if group[-1][4] - group[0][3] >= 2:
- yield '--- %d,%d ----%s' % (group[0][3] + 1, group[-1][4], lineterm)
- else:
- yield '--- %d ----%s' % (group[-1][4], lineterm)
- visiblechanges = []
- if visiblechanges:
- for tag, _, _, j1, j2 in group:
- if tag != 'delete':
- for line in b[j1:j2]:
- yield prefixmap[tag] + line
-
-
-
-
-
- def ndiff(a, b, linejunk = None, charjunk = IS_CHARACTER_JUNK):
- return Differ(linejunk, charjunk).compare(a, b)
-
-
- def restore(delta, which):
-
- try:
- tag = {
- 1: '- ',
- 2: '+ ' }[int(which)]
- except KeyError:
- raise ValueError, 'unknown delta choice (must be 1 or 2): %r' % which
-
- prefixes = (' ', tag)
- for line in delta:
- if line[:2] in prefixes:
- yield line[2:]
- continue
-
-
-
- def _test():
- import doctest
- import difflib
- return doctest.testmod(difflib)
-
- if __name__ == '__main__':
- _test()
-
-